<template>
	<div class="login-container">
		<video class="video"
			muted
			src="../../assets/video/bg-video.mp4"
			loop="loop"
			autoplay="true"></video>
		<div class="bg2"></div>
		<!-- 常规登入 -->
		<el-form :model="loginForm"
			status-icon
			:rules="rules"
			ref="loginForm"
			label-width="100px"
			class="login-loginForm">
			<h1 class="title"
				v-text="title"></h1>
			<!-- 一开始是二维码角标,点击之后变成电脑角标,再次点击又切换 -->

			<i @click="(isErweiLogin = !isErweiLogin), (isSmsLogin = false)"
				:class="['jiaobiao', 'iconfont', jiaobiao]"></i>
			<!-- 切换二维码登入的控制条件isErweiLogin -->
			<!-- 常规登入 -->
			<div class="common-login"
				v-if="!isErweiLogin && !isSmsLogin">
				<el-form-item label="用户名"
					prop="username">
					<el-input type="text"
						v-model="loginForm.username"
						autocomplete="off"></el-input>
				</el-form-item>

				<el-form-item label="密码"
					prop="password">
					<el-input type="password"
						v-model="loginForm.password"
						autocomplete="off"></el-input>
				</el-form-item>

				<el-form-item label="验证码"
					prop="captcha">
					<el-input maxlength="5"
						v-model="loginForm.captcha"
						class="captcha"
						ref="captcha"
						@keydown.native.enter="submitForm('loginForm')"></el-input>
					<span class="captcha-svg"
						v-loading="loading">
						<i @click="updateCaptcha"
							v-html="captchaSvg"></i>
					</span>
				</el-form-item>

				<el-form-item>
					<el-button type="primary"
						@click="submitForm('loginForm')">提交</el-button>
				</el-form-item>
				<!-- 手机登入图标按钮 -->
				<el-form-item>
					<div class="sms">
						<svg class="icon"
							aria-hidden="true">
							<use xlink:href="#icon-iphone"></use>
						</svg>
						<a href="javascript:;"
							@click="isSmsLogin = true"
							style="color: #fff; font-size: 16px">切换短信登入</a>
					</div>
				</el-form-item>
			</div>

			<!-- 二维码登入 -->
			<div class="erwei"
				v-else-if="isErweiLogin && !isSmsLogin">
				<div class="img"
					v-loading="qrLoading">
					<img :src="imgBase64Url"
						width="200px"
						alt="" />
					<i class="mask"
						:style="qrStyle"
						v-show="showQrMask"
						@click="getQrcode"> </i>
				</div>
				<p>
					<svg aria-hidden="true"
						class="icon-wx">
						<use xlink:href="#icon-weixin"></use>
					</svg>
					<b v-text="qrTip"></b>
				</p>
			</div>
			<!-- 短信验证码登入 -->
			<div class="smsContainer"
				v-else>
				<el-form-item label="手机号">
					<el-input maxlength="11"
						v-model="phoneNumber"
						class="captcha phone"></el-input>
					<span @click="sendSmsCode"
						class="captcha-svg"
						v-text="smsRetryMsg"
						style="color: #888; line-height: 45px; text-decoration: underline">
					</span>
				</el-form-item>
				<el-form-item label="验证码">
					<el-input v-model="smsCode"></el-input>
				</el-form-item>
				<el-form-item>
					<el-button type="primary"
						@click="smsSubmit">提交</el-button>
				</el-form-item>
			</div>
		</el-form>
	</div>
</template>
<script>
	//引入api中的方法
	import * as api from "@/api/users";
	//引入socket.io
	import socketIo from "socket.io-client";
	//引入生成二维码的插件qrcode
	import qr from "qrcode";
	//引入扫码成功和失效的图片
	import scancodeSuccessPic from "../../assets/img/scancode.png";
	import invalidPic from "../../assets/img/invalidQr.png";
	//映射vuex
	import { mapMutations } from "vuex";
	var validateCaptcha = (rule, value, callback) => {
		//callback只要传参了,表示表单验证不通过,不传参表示表单验证通过
		//value就是在input中的输入值
		//rule是个对象,就是验证对象
		if (value.length !== 5) {
			callback("验证码必须是5位");
		} else {
			callback();
		}
	};
	var validateUsername = (rule, value, callback) => {
		//callback只要传参了,表示表单验证不通过,不传参表示表单验证通过
		//value就是在input中的输入值
		//rule是个对象,就是验证对象
		var reg = /^\w{3,12}$/;

		if (reg.test(value)) {
			//验证通过
			callback();
		} else {
			callback("用户名可以是字母数字下划线,3-12位");
		}
	};
	var validatePass = (rule, value, callback) => {
		//callback只要传参了,表示表单验证不通过,不传参表示表单验证通过
		//value就是在input中的输入值
		//rule是个对象,就是验证对象
		if (value.length < 3) {
			callback("密码长度不能小于3位");
		} else {
			callback();
		}
	};

	export default {
		name: "login",
		data() {
			return {
				smsDisabled: false, //控制是否能够再次发送
				smsRetryMsg: "点击发送验证码", //xx秒之后重新发送提示
				smsCode: "", //短信验证码
				phoneNumber: "", //手机号
				codeLoading: false, //验证码加载动画
				loading: true, //加载动画布尔值
				title: "千锋管理系统",
				isErweiLogin: false, //是否是二维码登入
				captchaSvg: "", //验证码svg
				qrTip: "请使用手机微信扫码登入", //切换到二维码登入时的提示文字
				isSmsLogin: false, //短信登入
				showQrMask: false, //是否显示二维码遮罩
				qrLoading: true, //加载二维码的Loading动画
				loginForm: {
					//登入输入框的数据
					username: "",
					password: "",
					captcha: "",
				},
				rules: {
					//表单验证规则
					username: [{ validator: validateUsername, trigger: "blur" }],
					password: [{ validator: validatePass, trigger: "blur" }],
					captcha: [{ validator: validateCaptcha, trigger: "blur" }],
				},
				imgBase64Url: "", //二维码base64的图片地址
				isScanCodeSuccess: false, //是否扫码成功
				qrStyle: {
					backgroundImage: `url(${invalidPic})`,
				},
			};
		},
		//计算属性
		computed: {
			jiaobiao() {
				return this.isErweiLogin
					? "icon-diannaojiaobiao"
					: "icon-erweimajiaobiao";
			},
		},
		created() {
			//调用获取验证码的方法
			this.updateCaptcha();
		},
		methods: {
			//映射vuex的mutation
			...mapMutations(["SET_USERINFO"]),
			//封装短信登入相关的方法
			async sendSmsCode() {
				console.log(this.phoneNumber);
				//判断一下是否可以发送短信,通过smsDisabled来控制
				if (this.smsDisabled) {
					this.$message.error("1分钟内只能发送一次");
					return; //后面的逻辑不执行
				}
				//获取手机号,传递给后台,调用发送短信的接口
				let smsResult = await api.getSmsCode(this.phoneNumber);
				//解构内容
				let { state } = smsResult.data;
				if (state) {
					//锁住smsDisabled,不能再次发送了
					this.smsDisabled = true;
					//提示用户短信发送成功
					this.$message.success("短信发送成功");
					this.smsSecond = 60;
					//短信发送需要进入倒计时
					this.smsInterval = setInterval(() => {
						this.smsSecond--;
						if (this.smsSecond === 0) {
							//清除定时器
							clearInterval(this.smsInterval);
							//提示文字要复原
							this.smsRetryMsg = "点击发送验证码";
							//解锁smsDisabled 可以继续发送短信了
							this.smsDisabled = false;
							return;
						}
						this.smsRetryMsg = `${this.smsSecond}秒后重新发送`;
					}, 1000);
				}

				console.log(smsResult);
			},
			async smsSubmit() {
				let smsLoginRes = await api.smsLogin(this.smsCode);
				console.log(smsLoginRes);
				//判断登入状态,如果登入成功,将数据存储到本地
				let {
					userInfo,
					state,
					permission: { buttons },
					token,
				} = smsLoginRes.data;
				if (state) {
					localStorage.setItem("myx-permissionBtn", JSON.stringify(buttons));
					localStorage.setItem("myx-token", token);
					//调用vuex的方法,设置用户信息
					this.SET_USERINFO(userInfo);
					//跳转到欢迎页
					this.$router.push("/");
				}
			},
			//封装一个获取二维码地址的方法
			async getQrcode(sid) {
				//将提示文字变更
				this.qrTip = "请使用手机微信扫码登入";
				//清掉上一次二维码图片
				// this.imgBase64Url = ""
				//先关掉遮罩
				this.showQrMask = false;
				//把加载二维码动画打开
				this.qrLoading = true;
				sid = localStorage.getItem("myx-sid") ?? sid;
				//调用接口获取二维码url
				let qrResult = await api.getQrcode(sid);
				// console.log(qrResult);
				//解构 scanCodeUrl 和 后端的状态
				let { scanCodeUrl, state: getQrState } = qrResult.data;
				// console.log(scanCodeUrl);
				//判断服务器状态
				if (getQrState) {
					//如果请求成功
					//使用qrcode插件,将scanCodeUrl变成一个二维码
					qr.toDataURL(scanCodeUrl, (err, imgBase64Url) => {
						if (err) {
							//出错的情况
							this.$messageBox.error(err);
							return;
						}
						// console.log(imgBase64Url);
						this.imgBase64Url = imgBase64Url;

						//关掉二维码的加载动画
						this.qrLoading = false;
					});
				}
			},

			//封装一个方法,专门用于获取验证码
			updateCaptcha() {
				//打开加载动画
				this.loading = true;
				api.getCaptcha().then((res) => {
					// console.log(res);
					let { img } = res.data; //解构验证码
					this.captchaSvg = img;
					//关闭加载动画
					this.loading = false;
				});
			},
			//常规登入
			async submitForm(formName) {
				//登入逻辑

				//1.先要进行本地的表单校验

				//2.表单校验通过之后 通过v-model获取输入的username password

				//3.校验验证码

				//4.校验通过之后 发起请求 请求登入接口 传入用户名和密码

				//5.跳转到主页,显示主页
				//fromName是表单的ref名字
				// console.log(this.$refs);
				this.$refs[formName].validate((valid) => {
					// console.log(valid);
					if (valid) {
						//打开加载动画
						const loading = this.$loading({
							lock: true,
							text: "正在登入",
							spinner: "el-icon-loading",
							background: "rgba(0, 0, 0, 0.7)",
						});
						//本地表单校验通过
						let { username, password, captcha } = this.loginForm;
						//校验验证码
						api.verifyCaptcha(captcha).then(async (res) => {
							// console.log(res);
							let { state } = res.data; //解构返回的结构
							if (state) {
								//验证码正确
								let loginRes = await api.login(username, password);
								// console.log(loginRes);
								let { state: loginState, msg, token, userInfo } = loginRes.data;
								if (loginState) {
									//登入成功了
									//关闭登入加载动画
									loading.close();
									//将token存到localStorage
									localStorage.setItem("myx-token", token);
									//调用vuex的方法,设置用户信息
									this.SET_USERINFO(userInfo);
									//跳转页面
									this.$router.push("/");

									//提示登入成功
									this.$message({
										message: msg,
										type: "success",
										duration: 1000,
									});
								} else {
									//登入失败 关闭loading动画
									loading.close();
								}
							} else {
								//验证码校验失败 关闭Loading动画
								loading.close();
								//刷新验证码
								this.updateCaptcha();
							}
						});
					} else {
						//表单校验不通过
					}
				});
			},
			resetForm(formName) {
				this.$refs[formName].resetFields();
			},
		},
		watch: {
			//监听切换短信登入逻辑
			isSmsLogin(val) {
				//不是短信登入的时候,清掉定时器
				if (!val) {
					if (this.smsInterval) {
						clearInterval(this.smsInterval);
					}
					//将短信登入的文字提示复原
					this.smsRetryMsg = "点击发送验证码";
				}
			},
			//监听切换二维码登入的字段
			isErweiLogin(isErwei) {
				if (isErwei) {
					//切换成了二维码登入
					//打开二维码加载动画
					this.qrLoading = true;
					//需要把遮罩关掉
					this.showQrMask = false;
					//建立socket 连接
					//https协议,要使用wss协议
					let io = socketIo("wss://chst.vip");
					//扫码成功
					io.on("scancodeSuccess", async (data) => {
						//显示二维码的遮罩 并且将背景图片换成扫码成功的背景图片
						this.showQrMask = true;
						this.qrStyle.backgroundImage = `url(${scancodeSuccessPic})`;
						// console.log(data);
						//先解构内容
						let { state: scanCodeState, wechatCode } = data;
						if (scanCodeState) {
							//扫码成功了
							let scanCodeRes = await api.wechatLogin(wechatCode);
							// console.log(scanCodeRes);
							//解构内容
							let {
								state,
								userInfo,
								permission: { buttons },
								token,
							} = scanCodeRes.data;
							//把token userInfo permission存本地
							if (state) {
								localStorage.setItem("myx-userInfo", JSON.stringify(userInfo));
								localStorage.setItem(
									"myx-permissionBtn",
									JSON.stringify(buttons)
								);
								localStorage.setItem("myx-token", token);
								//调用vuex的方法,设置用户信息
								this.SET_USERINFO(userInfo);
								//跳转到欢迎页
								this.$router.push("/");
								//关闭二维码遮罩
								this.showQrMask = false;
							}
						}
					});
					//二维码失效
					io.on("invalidCode", (data) => {
						// console.log(data);
						let { state } = data;
						if (!state) {
							this.showQrMask = true;
							//将提示文字变更
							this.qrTip = "二维码失效,请点击重新获取二维码";
						}
					});
					//连接成功
					io.on("connectSuccess", async (data) => {
						// console.log(data);
						//从data中解构sid
						let { sid } = data;
						//把唯一标识存到本地
						localStorage.setItem("myx-sid", sid);
						//调用获取二维码的方法
						this.getQrcode(sid);
					});
				}
			},
		},
	};
</script>
<style scoped lang="less">
//样式设置不上的情况,解决方案
//1.检查类名是否正确
//2.检查权重是否正确
//3.检查是否需要穿透
.icon-wx {
	width: 25px !important;
	height: 25px !important;
	vertical-align: -7px;
	margin-right: 3px;
}
.login-container {
	text-align: center;
	color: #fff;

	.common-login {
		padding-right: 50px;
	}

	//二维码样式
	.erwei .img {
		display: inline-block;
		position: relative;
		width: 200px;
		height: 200px;

		img {
			position: absolute;
			left: 0;
		}

		.mask {
			width: 100%;
			height: 100%;
			opacity: 0.8;
			background-color: #fff;
			position: absolute;
			left: 0;
			// background-image: url("../../assets/img/scancode.png");
			background-size: 50%;
			background-repeat: no-repeat;
			background-position: center;
			cursor: pointer;
		}
	}

	.jiaobiao {
		font-size: 60px;
		color: #fff;
		position: absolute;
		right: -1px;
		top: -1px;
		cursor: pointer;
		opacity: 0.7;
	}

	.video {
		position: fixed;
		left: 0;
		top: 0;
		right: 0;
		bottom: 0;
	}

	.bg2 {
		background-image: url("../../assets/img/bg2.png");
		background-repeat: no-repeat;
		position: fixed;
		width: 20%;
		height: 40%;
		background-size: 100% 100%;
		left: 20%;
		top: 40%;
		opacity: 0.5;
	}

	.el-form {
		position: fixed;
		right: 10%;
		top: 25%;
		border-radius: 5px;
		width: 400px;
		background-color: rgba(0, 0, 0, 0.3);
		padding: 100px 0 50px 0;

		/deep/ .el-input__inner {
			width: 250px;
		}

		/deep/ .el-button--primary {
			background: linear-gradient(90deg, #1596fb, #002dff);
			width: 250px;
		}

		/deep/ .el-form-item__label {
			color: #fff;
		}

		.title {
			margin: 0 0 60px 0;
			text-align: center;
			color: #fff;
		}

		/deep/ .captcha {
			width: 100px;
			vertical-align: top;

			.el-input__inner {
				width: 100%;
				height: 45px;
				border-radius: 5px 0 0 5px;
				border: 0;
				font-size: 18px;
			}
		}

		svg path {
			stroke: red;
		}

		.captcha-svg {
			background: #fff;
			display: inline-block;
			height: 45px;
			width: 150px;
			text-align: center;
			cursor: pointer;
			border: 0;
			border-radius: 0px 5px 5px 0;
		}

		.el-form-item__content {
			margin-left: 30px !important;
			width: 250px !important;
		}
	}
}

.sms {
	margin-left: -15px !important;
	width: 250px !important;
}

.smsContainer {
	padding-right: 20px !important;
	width: 89%;

	/deep/ .el-form-item__label {
		// margin-left: 80px !important
		padding: 0 !important;
		padding-right: 10px !important;
	}

	/deep/ .phone {
		width: 140px !important;
	}

	/deep/ .captcha-svg {
		width: 115px !important;
	}

	/deep/ .el-form-item__content {
		margin: 0;
	}
}

// .smsContainer{
// 	width:300px;
// }
</style>
